package cn.com.libertymutual.sys.service.impl;

import java.util.Date;
import java.util.List;

import javax.annotation.Resource;
import javax.naming.directory.DirContext;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.ldap.core.ContextSource;
import org.springframework.ldap.core.DirContextOperations;
import org.springframework.ldap.core.LdapTemplate;
import org.springframework.ldap.core.support.AbstractContextMapper;
import org.springframework.ldap.filter.AndFilter;
import org.springframework.ldap.filter.EqualsFilter;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.ldap.LdapUtils;
import org.springframework.stereotype.Service;

import cn.com.libertymutual.core.exception.CustomLangException;
import cn.com.libertymutual.core.redis.util.RedisUtils;
import cn.com.libertymutual.core.security.ldap.LdapExceptionUtil;
import cn.com.libertymutual.core.util.Current;
import cn.com.libertymutual.core.web.ServiceResult;
import cn.com.libertymutual.sys.bean.SysUser;
import cn.com.libertymutual.sys.ldap.Person;
import cn.com.libertymutual.sys.ldap.PersonAttributeMapper;
import cn.com.libertymutual.sys.service.api.ILdapService;

import com.google.common.base.Throwables;


@Service("adServiceImpl")
public class AdServiceImpl implements ILdapService{
	 
	@Resource private  RedisUtils redisUtils;
	@Resource private LdapTemplate ldapTemplate;   
	@Resource private ContextSource contextSource; 
	private Logger log = LoggerFactory.getLogger(getClass());
	private final static class DnContextMapper extends AbstractContextMapper<String> {

		@Override
		protected String doMapFromContext(DirContextOperations ctx) {
			return ctx.getNameInNamespace();
		}
		
	}

	@Override
	public ServiceResult login(String userId, String userPwd) {
		ServiceResult rs = new ServiceResult();
		try {
			AndFilter filter = new AndFilter();
			
			//filter.and(new EqualsFilter("objectclass", "person")).and(new EqualsFilter("userPrincipalName", (String)authentication.getPrincipal()));
			filter.and(new EqualsFilter("objectclass", "person")).and(new EqualsFilter("sAMAccountName",userId ));
			
			List<String> results = ldapTemplate.search("", filter.encode(),  new DnContextMapper());

			if (results.size() != 1) Throwables.propagate( new BadCredentialsException("用户名或密码错误") );
			
			DirContext ctx = null;
			try {  
			    ctx = contextSource.getContext( results.get(0), (String)userPwd);  
			    rs.setSuccess();

			} catch (Exception e) {  //org.springframework.ldap.AuthenticationException: [LDAP: error code 49 - 80090308: LdapErr: DSID-0C0903A8, comment: AcceptSecurityContext error, data 52e, v1db1
				log.error( e.getMessage() );
				LdapExceptionUtil eu =  new LdapExceptionUtil( e );
				rs.setAppFail();
				rs.setResCode(String.valueOf(eu.getErrorCode()));
				rs.setResult(eu.getErrorMessage()); 
				
			} finally {  
			    LdapUtils.closeContext(ctx);  
			    //org.springframework.ldap.support.LdapUtils.closeContext(ctx);
			}
		} catch (Exception cea) {
			CustomLangException ce = new CustomLangException(cea);
			rs.setAppFail();
			rs.setResCode(ce.getErrorCodeStr());
			rs.setResult(ce.getErrorMessage()); 
		}  
		return rs;
	}
	@Override
	public DirContext getDirContext(String userId, String userPwd) {
		// TODO Auto-generated method stub 
		return null;
	}
	@Override
	public ServiceResult getUserInfoFromLdap(String userId) { 
		ServiceResult rs = new ServiceResult();
		try {
			SysUser  user =new SysUser();
			AndFilter filter = new AndFilter();
			
			//filter.and(new EqualsFilter("objectclass", "person")).and(new EqualsFilter("userPrincipalName", (String)authentication.getPrincipal()));
			filter.and(new EqualsFilter("objectclass", "person")).and(new EqualsFilter("sAMAccountName",userId ));
			List<Person> results = ldapTemplate.search("", filter.encode(),new  PersonAttributeMapper() );

			if (results.size() != 1) Throwables.propagate( new BadCredentialsException("未查询到用户") );
			Person person =results.get(0);
			user.setCreated(new Date());
			user.setBranchcode(person.getCompany());
			//user.setCreater(Current.userInfo.get().getUserId());
			user.setDeptcode(person.getDepartment());
			user.setEmail(person.getMail());
			user.setMobileno(person.getMobile());
			user.setPhoneno(person.getTelephoneNumber());
			user.setUserid(person.getsAMAccountName().toLowerCase());
			user.setUsername(person.getDisplayName()); 
			rs.setSuccess();
			rs.setResult(user); 
		} catch (Exception cea) {
			CustomLangException ce = new CustomLangException(cea);
			rs.setAppFail();
			rs.setResCode(ce.getErrorCodeStr());
			rs.setResult(ce.getErrorMessage()); 
		}  
		return rs;
	}
	
	
	
	
}
